package jnpf.fico.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.base.service.IBaseSerialNumberService;
import jnpf.fico.entity.ZcBillEntity;
import jnpf.fico.entity.ZcBillItemEntity;
import jnpf.fico.entity.ZcglCwSzEntity;
import jnpf.fico.entity.ZcglCwSzItemEntity;
import jnpf.fico.mapper.ZcBillItemMapper;
import jnpf.fico.mapper.ZcBillMapper;
import jnpf.fico.mapper.ZcglCwSzItemMapper;
import jnpf.fico.mapper.ZcglCwSzMapper;
import jnpf.fico.model.bill.ZcBillReduceItemDTO;
import jnpf.fico.model.sz.*;
import jnpf.fico.service.ZcglCwSzItemService;
import jnpf.fico.service.ZcglCwSzService;
import jnpf.model.visiual.superQuery.ConditionJsonModel;
import jnpf.model.visiual.superQuery.SuperQueryConditionModel;
import jnpf.model.visiual.superQuery.SuperQueryJsonModel;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.model.authorize.AuthorizeConditionModel;
import jnpf.permission.service.AuthorizeService;
import jnpf.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 收支详情
 * 版本： V3.2.0
 * 版权： 智果云科技（https://www.jnpfsoft.com）
 * 作者： JNPF开发平台组
 * 日期： 2024-10-25
 */
@Service
public class ZcglCwSzServiceImpl extends ServiceImpl<ZcglCwSzMapper, ZcglCwSzEntity> implements ZcglCwSzService {


    @Autowired
    private GeneraterSwapUtil generaterSwapUtil;

    @Autowired
    private UserProvider userProvider;

    @Autowired
    private AuthorizeService authorizeService;

    @Autowired
    private ZcglCwSzItemService zcglCwSzItemService;

    @Autowired
    private ZcBillMapper zcBillMapper;
    @Autowired
    private ZcBillItemMapper zcBillItemMapper;
    @Autowired
    private ZcglCwSzItemMapper zcglCwSzItemMapper;
    @Autowired
    private IBaseSerialNumberService iBaseSerialNumberService;


    @Override
    public List<ZcglCwSzEntity> getList(ZcglCwSzPagination zcglCwSzPagination) {
        return getTypeList(zcglCwSzPagination, zcglCwSzPagination.getDataType());
    }

    @Override
    public List<ZcglCwSzEntity> getTypeList(ZcglCwSzPagination zcglCwSzPagination, String dataType) {
        String userId = userProvider.get().getUserId();
        List<String> AllIdList = new ArrayList();
        List<List<String>> intersectionList = new ArrayList<>();
        int total = 0;
        int zcglCwSzNum = 0;
        QueryWrapper<ZcglCwSzEntity> zcglCwSzQueryWrapper = new QueryWrapper<>();
        int zcglCwSzItemNum = 0;
        QueryWrapper<ZcglCwSzItemEntity> zcglCwSzItemQueryWrapper = new QueryWrapper<>();
        long zcglCwSzItemcount = zcglCwSzItemService.count();
        List<String> allSuperIDlist = new ArrayList<>();
        String superOp = "";
        if (ObjectUtil.isNotEmpty(zcglCwSzPagination.getSuperQueryJson())) {
            SuperQueryJsonModel superQueryJsonModel = JsonUtil.getJsonToBean(zcglCwSzPagination.getSuperQueryJson(), SuperQueryJsonModel.class);
            String matchLogic = superQueryJsonModel.getMatchLogic();
            List<ConditionJsonModel> superQueryList = JsonUtil.getJsonToList(superQueryJsonModel.getConditionJson(), ConditionJsonModel.class);
            for (ConditionJsonModel conditionjson : superQueryList) {
                Map<String, Object> map = JsonUtil.stringToMap(conditionjson.getAttr());
                Map<String, Object> configMap = JsonUtil.stringToMap(map.get("__config__").toString());
                String tableName = configMap.get("relationTable") != null ? String.valueOf(configMap.get("relationTable")) : String.valueOf(configMap.get("tableName"));
                if (map.get("multiple") != null) {
                    if (Boolean.valueOf(String.valueOf(map.get("multiple"))) && ObjectUtil.isNull(conditionjson.getFieldValue())) {
                        conditionjson.setFieldValue("[]");
                    }
                }
                conditionjson.setTableName(tableName);
            }
            List<String> allSuperList = new ArrayList<>();
            List<List<String>> intersectionSuperList = new ArrayList<>();
            int zcglCwSzNum1 = 0;
            QueryWrapper<ZcglCwSzEntity> zcglCwSzSuperWrapper = new QueryWrapper<>();
            zcglCwSzNum1 = generaterSwapUtil.getCondition(new SuperQueryConditionModel(zcglCwSzSuperWrapper, superQueryList, matchLogic, "zcglCwSz")
                    , new ZcglCwSzEntity(), zcglCwSzNum1);
            if (zcglCwSzNum1 > 0) {
                List<String> zcglCwSzList = this.list(zcglCwSzSuperWrapper).stream().map(ZcglCwSzEntity::getId).collect(Collectors.toList());
                allSuperList.addAll(zcglCwSzList);
                intersectionSuperList.add(zcglCwSzList);
            }
            int zcglCwSzItemNum1 = 0;
            QueryWrapper<ZcglCwSzItemEntity> zcglCwSzItemSuperWrapper = new QueryWrapper<>();
            zcglCwSzItemNum1 = generaterSwapUtil.getCondition(new SuperQueryConditionModel(zcglCwSzItemSuperWrapper, superQueryList, matchLogic, "zcglCwSzItem")
                    , new ZcglCwSzItemEntity(), zcglCwSzItemNum1);
            if (zcglCwSzItemNum1 > 0 && zcglCwSzItemcount > 0) {
                List<String> zcglCwSzItemList = zcglCwSzItemService.list(zcglCwSzItemSuperWrapper).stream().map(ZcglCwSzItemEntity::getParentid).collect(Collectors.toList());
                allSuperList.addAll(zcglCwSzItemList);
                intersectionSuperList.add(zcglCwSzItemList);
            }
            superOp = matchLogic;
            //and or
            if (matchLogic.equalsIgnoreCase("and")) {
                allSuperIDlist = generaterSwapUtil.getIntersection(intersectionSuperList);
            } else {
                allSuperIDlist = allSuperList;
            }
        }
        boolean pcPermission = false;
        boolean appPermission = false;
        boolean isPc = ServletUtil.getHeader("jnpf-origin").equals("pc");
        if (isPc && pcPermission) {
            if (!userProvider.get().getIsAdministrator()) {
                Object zcglCwSzObj = authorizeService.getCondition(new AuthorizeConditionModel(zcglCwSzQueryWrapper, zcglCwSzPagination.getMenuId(), "zcgl_cw_sz"));
                if (ObjectUtil.isEmpty(zcglCwSzObj)) {
                    return new ArrayList<>();
                } else {
                    zcglCwSzQueryWrapper = (QueryWrapper<ZcglCwSzEntity>) zcglCwSzObj;
                    zcglCwSzNum++;
                }
                Object zcglCwSzItemObj = authorizeService.getCondition(new AuthorizeConditionModel(zcglCwSzItemQueryWrapper, zcglCwSzPagination.getMenuId(), "zcgl_cw_sz_item"));
                if (ObjectUtil.isEmpty(zcglCwSzItemObj)) {
                    return new ArrayList<>();
                } else {
                    zcglCwSzItemQueryWrapper = (QueryWrapper<ZcglCwSzItemEntity>) zcglCwSzItemObj;
                    zcglCwSzItemNum++;
                }
            }
        }
        if (!isPc && appPermission) {
            if (!userProvider.get().getIsAdministrator()) {
                Object zcglCwSzObj = authorizeService.getCondition(new AuthorizeConditionModel(zcglCwSzQueryWrapper, zcglCwSzPagination.getMenuId(), "zcglCwSz"));
                if (ObjectUtil.isEmpty(zcglCwSzObj)) {
                    return new ArrayList<>();
                } else {
                    zcglCwSzQueryWrapper = (QueryWrapper<ZcglCwSzEntity>) zcglCwSzObj;
                    zcglCwSzNum++;
                }


                Object zcglCwSzItemObj = authorizeService.getCondition(new AuthorizeConditionModel(zcglCwSzItemQueryWrapper, zcglCwSzPagination.getMenuId(), "zcglCwSzItem"));
                if (ObjectUtil.isEmpty(zcglCwSzItemObj)) {
                    return new ArrayList<>();
                } else {
                    zcglCwSzItemQueryWrapper = (QueryWrapper<ZcglCwSzItemEntity>) zcglCwSzItemObj;
                    zcglCwSzItemNum++;
                }


            }
        }
        if (isPc) {
            if (ObjectUtil.isNotEmpty(zcglCwSzPagination.getTransactionTime())) {
                zcglCwSzNum++;
                zcglCwSzQueryWrapper.lambda().like(ZcglCwSzEntity::getTransactionTime, zcglCwSzPagination.getTransactionTime());
            }

        }
        if (zcglCwSzItemNum > 0) {
            List<String> zcglCwSzItemIdList = zcglCwSzItemService.list(zcglCwSzItemQueryWrapper).stream().filter(t -> StringUtil.isNotEmpty(t.getParentid())).map(t -> t.getParentid()).collect(Collectors.toList());
            long count = zcglCwSzItemService.count();
            if (count > 0) {
                intersectionList.add(zcglCwSzItemIdList);
            }
            AllIdList.addAll(zcglCwSzItemIdList);
        }
        total += zcglCwSzItemNum;
        List<String> intersection = generaterSwapUtil.getIntersection(intersectionList);
        if (total > 0) {
            if (intersection.size() == 0) {
                intersection.add("jnpfNullList");
            }
            zcglCwSzQueryWrapper.lambda().in(ZcglCwSzEntity::getId, intersection);
        }
        //是否有高级查询
        if (StringUtil.isNotEmpty(superOp)) {
            if (allSuperIDlist.size() == 0) {
                allSuperIDlist.add("jnpfNullList");
            }
            List<String> finalAllSuperIDlist = allSuperIDlist;
            zcglCwSzQueryWrapper.lambda().and(t -> t.in(ZcglCwSzEntity::getId, finalAllSuperIDlist));
        }

        //排序
        if (StringUtil.isEmpty(zcglCwSzPagination.getSidx())) {
            zcglCwSzQueryWrapper.lambda().orderByDesc(ZcglCwSzEntity::getId);
        } else {
            try {
                String sidx = zcglCwSzPagination.getSidx();
                ZcglCwSzEntity zcglCwSzEntity = new ZcglCwSzEntity();
                Field declaredField = zcglCwSzEntity.getClass().getDeclaredField(sidx);
                declaredField.setAccessible(true);
                String value = declaredField.getAnnotation(TableField.class).value();
                zcglCwSzQueryWrapper = "asc".equals(zcglCwSzPagination.getSort().toLowerCase()) ? zcglCwSzQueryWrapper.orderByAsc(value) : zcglCwSzQueryWrapper.orderByDesc(value);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        if ("0".equals(dataType)) {
            if ((total > 0 && AllIdList.size() > 0) || total == 0) {
                Page<ZcglCwSzEntity> page = new Page<>(zcglCwSzPagination.getCurrentPage(), zcglCwSzPagination.getPageSize());
                IPage<ZcglCwSzEntity> userIPage = this.page(page, zcglCwSzQueryWrapper);
                return zcglCwSzPagination.setData(userIPage.getRecords(), userIPage.getTotal());
            } else {
                List<ZcglCwSzEntity> list = new ArrayList();
                return zcglCwSzPagination.setData(list, list.size());
            }
        } else {
            return this.list(zcglCwSzQueryWrapper);
        }
    }


    @Override
    public ZcglCwSzEntity getInfo(String id) {
        QueryWrapper<ZcglCwSzEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ZcglCwSzEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    public void create(ZcglCwSzEntity entity) {
        this.save(entity);
    }

    @Override
    public boolean update(String id, ZcglCwSzEntity entity) {
        return this.updateById(entity);
    }

    @Override
    public void delete(ZcglCwSzEntity entity) {
        if (entity != null) {
            this.removeById(entity.getId());
        }
    }

    //子表方法
    @Override
    public List<ZcglCwSzItemEntity> getZcglCwSzItemList(String id, ZcglCwSzPagination zcglCwSzPagination) {
        QueryWrapper<ZcglCwSzItemEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper = zcglCwSzItemService.getChild(zcglCwSzPagination, queryWrapper);
        queryWrapper.lambda().eq(ZcglCwSzItemEntity::getParentid, id);
        return zcglCwSzItemService.list(queryWrapper);
    }

    @Override
    public List<ZcglCwSzItemEntity> getZcglCwSzItemList(String id) {
        QueryWrapper<ZcglCwSzItemEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ZcglCwSzItemEntity::getParentid, id);
        return zcglCwSzItemService.list(queryWrapper);
    }

    //列表子表数据方法


    //验证表单唯一字段
    @Override
    public boolean checkForm(ZcglCwSzForm form, int i) {
        int total = 0;
        boolean isUp = StringUtil.isNotEmpty(form.getId()) && !form.getId().equals("0");
        String id = "";
        if (isUp) {
            id = form.getId();
        }
        if (form.getZcglcwszitemList() != null) {
        }
        if (total > 0) {
            return true;
        }
        return false;
    }

    @Override
    public ActionResult receive(ZcglCwSzForm zcglCwSzForm) {

        /*
        * 收款接口逻辑
        *   1.生成收支详情
        *   2.每次收款在账单详情里面累加
        *   3.生成交易单号
        * */

        String mainId = RandomUtil.uuId();
        UserInfo userInfo = userProvider.get();
        UserEntity userEntity = generaterSwapUtil.getUser(userInfo.getUserId());
        ZcglCwSzEntity entity = JsonUtil.getJsonToBean(zcglCwSzForm, ZcglCwSzEntity.class);
        entity.setId(mainId);
        entity.setCreatoruserid(userEntity.getId());
        entity.setCreatortime(new Date());




        //生成交易号
        entity.setTransactionNo(iBaseSerialNumberService.getSerialNumber("P",8));

        //根据账单id获取账单信息
        ZcBillEntity zcBillEntity = zcBillMapper.selectById(zcglCwSzForm.getBillId());

        //更新主表字段
        entity.setCustomerName(zcBillEntity.getCustomerName());
        entity.setBillNo(zcBillEntity.getBillNo());
        entity.setLeaseSpace(zcBillEntity.getLeaseSpace());






        if(IterUtil.isNotEmpty(zcglCwSzForm.getZcglcwszitemList())){
            List<ZcglCwSzItemModel> zcglcwszitemList = zcglCwSzForm.getZcglcwszitemList();
            zcglcwszitemList.stream().forEach(i->{
                //根据账单id+费用项获取账单详情
                ZcBillItemEntity zcBillItemEntity = zcBillItemMapper.selectOne(new QueryWrapper<ZcBillItemEntity>()
                        .eq("F_ParentId", zcglCwSzForm.getBillId())
                        .eq("EXPENSE_ITEM", i.getExpenseItem())
                );
                if(ObjectUtil.isNotNull(zcBillItemEntity)){

                    //已收本金额累加
                    zcBillItemEntity.setReceivedAmount(BigDecimal.valueOf(zcBillItemEntity.getReceivedAmount().doubleValue()+i.getTransactionAmount().doubleValue()));
                    //待收本金额递减
                    zcBillItemEntity.setPendAmount(BigDecimal.valueOf(zcBillItemEntity.getPendAmount().doubleValue()-i.getTransactionAmount().doubleValue()));
//                    if(i.getUnpaidAmount().doubleValue()<i.getReceivedAmount().doubleValue()){
//                        throw new RuntimeException("实收金额不能大于待收金额");
//                    }
                    zcBillItemMapper.updateById(zcBillItemEntity);
                }

                //收支详情添加数据   预防空指针
                i.setReceiveAmount(zcBillItemEntity!=null?zcBillItemEntity.getPendAmount():new BigDecimal(0.0));
                i.setTransactionAmount(i.getTransactionAmount());
                ZcglCwSzItemEntity zcglCwSzItemEntity = new ZcglCwSzItemEntity();
                BeanUtil.copyProperties(i,zcglCwSzItemEntity);
                zcglCwSzItemEntity.setId(RandomUtil.uuId());
                zcglCwSzItemEntity.setParentid(entity.getId());
                zcglCwSzItemEntity.setReceiveAmount(zcBillItemEntity.getRealAmount());
                zcglCwSzItemEntity.setStatus(ZcglCwSzItemEntity.STATUS_1);
                //设置未收金额
                zcglCwSzItemEntity.setUnpaidAmount(zcBillItemEntity.getPendAmount());
                zcglCwSzItemEntity.setCreatortime(new Date());
                zcglCwSzItemMapper.insert(zcglCwSzItemEntity);
            });
        }
        this.save(entity);

        return ActionResult.success("收款成功");
    }

    @Override
    public IPage<ZcglCwSzListVO> getListPage(ZcglCwSzPagination zcglCwSzPagination) {

        return this.baseMapper.getListPage(new Page<ZcBillReduceItemDTO>(zcglCwSzPagination.getCurrentPage(), zcglCwSzPagination.getPageSize()),zcglCwSzPagination);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActionResult nullify(ZcglCwSzForm zcglCwSzForm) {

        /*
        * 收支明细作废逻辑
        *   1.将账单详情里面的已收本金额、待收本金额更改
        *   2.更改收支详情状态
        * */

        //根据账单id+费用项获取账单详情
        ZcBillItemEntity zcBillItemEntity = zcBillItemMapper.selectOne(new QueryWrapper<ZcBillItemEntity>()
                .eq("F_ParentId", zcglCwSzForm.getBillId())
                .eq("EXPENSE_ITEM", zcglCwSzForm.getExpenseItem())
        );
        if(ObjectUtil.isNotNull(zcBillItemEntity)){

            //已收本金额递减
            zcBillItemEntity.setReceivedAmount(BigDecimal.valueOf(zcBillItemEntity.getReceivedAmount().doubleValue()-zcglCwSzForm.getTransactionAmount().doubleValue()));
            //待收本金额累加
            zcBillItemEntity.setPendAmount(BigDecimal.valueOf(zcBillItemEntity.getPendAmount().doubleValue()+zcglCwSzForm.getTransactionAmount().doubleValue()));
            zcBillItemMapper.updateById(zcBillItemEntity);
        }

        ZcglCwSzItemEntity zcglCwSzItemEntity = zcglCwSzItemMapper.selectById(zcglCwSzForm.getId());
        zcglCwSzItemEntity.setStatus(ZcglCwSzItemEntity.STATUS_2);
        zcglCwSzItemMapper.updateById(zcglCwSzItemEntity);

        return ActionResult.success("操作成功");
    }

    @Override
    public ZcglCwSzSumMoneyDTO getSumMoney() {
        ZcglCwSzSumMoneyDTO zcglCwSzSumMoneyDTO = baseMapper.getSumMoney();
        if(ObjectUtil.isNotNull(zcglCwSzSumMoneyDTO)){
            BigDecimal sumReceived = zcglCwSzSumMoneyDTO.getSumReceived() != null ? zcglCwSzSumMoneyDTO.getSumReceived() : BigDecimal.ZERO;
            BigDecimal sumRt = zcglCwSzSumMoneyDTO.getSumRt() != null ? zcglCwSzSumMoneyDTO.getSumRt() : BigDecimal.ZERO;
            zcglCwSzSumMoneyDTO.setSumCount(sumReceived.subtract(sumRt));
        }
        return zcglCwSzSumMoneyDTO;
    }

    @Override
    public ZcglCwRefundSumMoneyDTO getSumTkMoney() {
        ZcglCwRefundSumMoneyDTO zcglCwRefundSumMoneyDTO = baseMapper.getSumTkMoney();
        return zcglCwRefundSumMoneyDTO;
    }


}
